package com.fr.report.cellElement.core;

import com.fr.base.FRContext;
import com.fr.base.core.ComparatorUtils;
import com.fr.base.core.list.IntList;
import com.fr.base.xml.XMLPrintWriter;
import com.fr.base.xml.XMLableReader;
import com.fr.data.TableData;
import com.fr.data.TableDataException;
import com.fr.report.cellElement.Formula;
import com.fr.report.core.ScriptUtils;
import com.fr.report.script.Calculator;
import com.fr.report.script.Primitive;
import com.fr.report.script.SingleRowNameSpace;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

public class FunctionGrouper extends RecordGrouper
{
  public static final int GROUPING_MODE = 0;
  public static final int LIST_MODE = 1;
  public static final int CONTINUUM_MODE = 2;
  private int divideMode = 0;
  private boolean isCustom = false;
  private String formulaContent = null;

  public boolean isCustom()
  {
    return this.isCustom;
  }

  public void setCustom(boolean paramBoolean)
  {
    this.isCustom = paramBoolean;
  }

  public int getDivideMode()
  {
    return this.divideMode;
  }

  public void setDivideMode(int paramInt)
  {
    this.divideMode = paramInt;
  }

  public String getFormulaContent()
  {
    return this.formulaContent;
  }

  public void setFormulaContent(String paramString)
  {
    this.formulaContent = paramString;
  }

  public Group[] group(TableData paramTableData, int paramInt, int[] paramArrayOfInt, Calculator paramCalculator)
  {
    Group[] arrayOfGroup;
    Object localObject1;
    int i;
    Object localObject2;
    int k;
    Object localObject3;
    if (paramInt == -1)
      return super.group(paramTableData, paramInt, paramArrayOfInt, paramCalculator);
    if (paramArrayOfInt == null)
      try
      {
        paramArrayOfInt = IntList.range(paramTableData.getRowCount());
      }
      catch (TableDataException localTableDataException)
      {
        FRContext.getLogger().log(Level.WARNING, localTableDataException.getMessage(), localTableDataException);
      }
    SingleRowNameSpace localSingleRowNameSpace = new SingleRowNameSpace(paramTableData, -1, null);
    paramCalculator.pushNameSpace(localSingleRowNameSpace);
    if (this.divideMode == 0)
    {
      localObject1 = new HashMap();
      ArrayList localArrayList = new ArrayList();
      localObject2 = new ArrayList();
      for (int j = 0; j < paramArrayOfInt.length; ++j)
      {
        k = paramArrayOfInt[j];
        localObject3 = current_v(paramTableData, k, paramInt, localSingleRowNameSpace, paramCalculator);
        IntList localIntList2 = (IntList)((Map)localObject1).get(localObject3);
        if (localIntList2 == null)
        {
          localIntList2 = new IntList();
          localIntList2.add(k);
          localArrayList.add(localObject3);
          ((List)localObject2).add(localIntList2);
          ((Map)localObject1).put(localObject3, localIntList2);
        }
        else
        {
          localIntList2.add(k);
        }
      }
      arrayOfGroup = new Group[localArrayList.size()];
      j = 0;
      k = localArrayList.size();
      while (true)
      {
        if (j >= k)
          break label577;
        arrayOfGroup[j] = new Group(localArrayList.get(j), ((IntList)((List)localObject2).get(j)).toArray());
        ++j;
      }
    }
    if (this.divideMode == 2)
    {
      localObject1 = new ArrayList();
      if (paramArrayOfInt.length > 0)
      {
        i = paramArrayOfInt[0];
        localObject2 = current_v(paramTableData, i, paramInt, localSingleRowNameSpace, paramCalculator);
        IntList localIntList1 = new IntList();
        localIntList1.add(i);
        for (k = 1; k < paramArrayOfInt.length; ++k)
        {
          i = paramArrayOfInt[k];
          localObject3 = current_v(paramTableData, i, paramInt, localSingleRowNameSpace, paramCalculator);
          if (ComparatorUtils.equals(localObject2, localObject3))
          {
            localIntList1.add(i);
          }
          else
          {
            ((List)localObject1).add(new Group(localObject2, localIntList1.toArray()));
            localObject2 = localObject3;
            localIntList1 = new IntList();
            localIntList1.add(i);
          }
        }
        ((List)localObject1).add(new Group(localObject2, localIntList1.toArray()));
      }
      arrayOfGroup = (Group[])((List)localObject1).toArray(new Group[((List)localObject1).size()]);
    }
    else
    {
      localObject1 = new ArrayList();
      for (i = 0; i < paramArrayOfInt.length; ++i)
        ((List)localObject1).add(new Group(current_v(paramTableData, paramArrayOfInt[i], paramInt, localSingleRowNameSpace, paramCalculator), new int[] { paramArrayOfInt[i] }));
      arrayOfGroup = (Group[])((List)localObject1).toArray(new Group[((List)localObject1).size()]);
    }
    label577: paramCalculator.removeNameSpace(localSingleRowNameSpace);
    return ((Group)(Group)arrayOfGroup);
  }

  public Iterator groupIterator(TableData paramTableData, int paramInt, int[] paramArrayOfInt, Calculator paramCalculator)
  {
    if (this.divideMode == 1)
      return new MonoGrouper().groupIterator(paramTableData, paramInt, paramArrayOfInt, paramCalculator);
    if (this.divideMode == 2)
      return new ContinuumIterator(paramTableData, paramInt, paramArrayOfInt, paramCalculator);
    return new ContinuumIterator(paramTableData, paramInt, paramArrayOfInt, paramCalculator);
  }

  private Object current_v(TableData paramTableData, int paramInt1, int paramInt2, SingleRowNameSpace paramSingleRowNameSpace, Calculator paramCalculator)
  {
    Object localObject = null;
    try
    {
      localObject = paramTableData.getValueAt(paramInt1, paramInt2);
    }
    catch (TableDataException localTableDataException)
    {
      FRContext.getLogger().log(Level.WARNING, localTableDataException.getMessage(), localTableDataException);
    }
    if ((this.isCustom == true) && (this.formulaContent != null))
    {
      paramSingleRowNameSpace.setRowIndex(paramInt1);
      paramSingleRowNameSpace.setCurrentValue(localObject);
      localObject = ScriptUtils.executeFormula(paramCalculator, new Formula(this.formulaContent));
    }
    return localObject;
  }

  public void readXML(XMLableReader paramXMLableReader)
  {
    if (paramXMLableReader.isChildNode())
    {
      String str1;
      String str2 = paramXMLableReader.getTagName();
      if ("Attr".equals(str2))
        if ((str1 = paramXMLableReader.getAttr("divideMode")) != null)
          setDivideMode(Integer.valueOf(str1).intValue());
      else if ("Custom".equals(str2))
        if ((str1 = paramXMLableReader.getAttr("isCustom")) != null)
          setCustom(Boolean.valueOf(str1).booleanValue());
      else if ("FC".equals(str2))
        this.formulaContent = paramXMLableReader.getElementValue();
    }
  }

  public void writeXML(XMLPrintWriter paramXMLPrintWriter)
  {
    if (this.divideMode != 0)
      paramXMLPrintWriter.startTAG("Attr").attr("divideMode", this.divideMode).end();
    if (this.isCustom == true)
      paramXMLPrintWriter.startTAG("Custom").attr("isCustom", this.isCustom).end();
    if (this.formulaContent != null)
      paramXMLPrintWriter.startTAG("FC").textNode(this.formulaContent).end();
  }

  private static class ContinuumIterator
    implements Iterator
  {
    private TableData data;
    private int columnIndex;
    private int[] rows;
    private Calculator calculator;
    private int nextArrayIndex = -1;
    private int nextTableDataIndex = -1;
    private Group nextGroup;
    private int current_group_index = -1;
    private int need_group_index = 0;

    ContinuumIterator(TableData paramTableData, int paramInt, int[] paramArrayOfInt, Calculator paramCalculator)
    {
      this.data = paramTableData;
      this.columnIndex = paramInt;
      this.rows = paramArrayOfInt;
      this.calculator = paramCalculator;
    }

    private void nextRowIndex()
    {
      if (this.rows == null)
      {
        this.nextTableDataIndex += 1;
      }
      else
      {
        this.nextArrayIndex += 1;
        if (this.nextArrayIndex >= this.rows.length)
          this.nextTableDataIndex = -1;
        else
          this.nextTableDataIndex = this.rows[this.nextArrayIndex];
      }
    }

    private Object getObject(int paramInt)
    {
      try
      {
        if ((paramInt < 0) || (!(this.data.hasRow(paramInt))))
          return Primitive.NULL;
        if (this.columnIndex == -1)
          return new Integer(paramInt + 1);
        return this.data.getValueAt(paramInt, this.columnIndex);
      }
      catch (TableDataException localTableDataException)
      {
        FRContext.getLogger().log(Level.WARNING, localTableDataException.getMessage(), localTableDataException);
      }
      return Primitive.NULL;
    }

    private void findNext()
    {
      nextRowIndex();
      Object localObject = getObject(this.nextTableDataIndex);
      if (ComparatorUtils.equals(localObject, Primitive.NULL))
      {
        this.nextGroup = null;
        return;
      }
      IntList localIntList = new IntList();
      localIntList.add(this.nextTableDataIndex);
      int i = this.nextTableDataIndex;
      int j = this.nextArrayIndex;
      nextRowIndex();
      while ((this.nextTableDataIndex > i) && (ComparatorUtils.equals(getObject(this.nextTableDataIndex), localObject)))
      {
        localIntList.add(this.nextTableDataIndex);
        i = this.nextTableDataIndex;
        j = this.nextArrayIndex;
        nextRowIndex();
      }
      this.nextTableDataIndex = i;
      this.nextArrayIndex = j;
      this.nextGroup = new Group(localObject, localIntList.toArray());
    }

    public boolean hasNext()
    {
      while (this.current_group_index < this.need_group_index)
      {
        findNext();
        this.current_group_index += 1;
      }
      return (this.nextGroup != null);
    }

    public Object next()
    {
      while (this.current_group_index < this.need_group_index)
      {
        findNext();
        this.current_group_index += 1;
      }
      this.need_group_index += 1;
      return this.nextGroup;
    }

    public void remove()
    {
      throw new UnsupportedOperationException();
    }
  }
}